"""
任务管理API路由
"""
from typing import Optional, List
from fastapi import APIRouter, Depends, HTTPException,  Query
from fastapi import status as HTTP_STATUS
from sqlalchemy.orm import Session
from sqlalchemy import desc, func
from datetime import datetime

from core.database import get_db
from api.auth import get_current_user, get_current_admin, get_current_user_optional
from models.database import User, ParseTask, ParseResult, SliceTask
from models.schemas import (
    ParseTaskResponse, BaseResponse, PaginatedResponse, TaskStatus
)
from core.config import get_settings
from core.logger import api_logger

router = APIRouter()
settings = get_settings()


@router.get("/my-tasks", response_model=PaginatedResponse)
async def get_my_tasks(
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    status: Optional[str] = Query(None),
    mode: Optional[str] = Query(None),
    search: Optional[str] = Query(None),
    current_user: Optional[User] = Depends(get_current_user_optional),
    db: Session = Depends(get_db)
):
    """获取当前用户的任务列表（Web界面用）"""
    try:
        # 如果用户未登录，返回空列表
        if current_user is None:
            return {
                "items": [],
                "total": 0,
                "page": page,
                "limit": page_size,
                "pages": 0,
                "stats": {
                    "total": 0,
                    "pending": 0,
                    "processing": 0,
                    "completed": 0,
                    "failed": 0
                }
            }
        
        # 构建基础查询
        base_query = db.query(ParseTask).filter(ParseTask.user_id == current_user.id)
        
        # 构建筛选查询
        query = base_query
        
        # 按状态筛选
        if status:
            query = query.filter(ParseTask.status == status)
            api_logger.log_task_event("tasks", "filter_by_status", {"status": status})
        
        # 按模式筛选
        if mode:
            query = query.filter(ParseTask.execution_mode == mode)
            api_logger.log_task_event("tasks", "filter_by_mode", {"mode": mode})
        
        # 搜索
        if search:
            query = query.filter(
                ParseTask.task_id.contains(search) | 
                ParseTask.filename.contains(search)
            )
        
        # 获取筛选后的总数
        total = query.count()
        
        # 分页查询
        tasks = query.order_by(desc(ParseTask.created_at)).offset((page - 1) * page_size).limit(page_size).all()
        
        # 计算分页信息
        pages = (total + page_size - 1) // page_size
        
        # 获取统计信息（基于基础查询，不受筛选影响）- 使用单次查询优化
        from sqlalchemy import func, case
        
        stats_query = base_query.with_entities(
            func.count(ParseTask.id).label('total'),
            func.sum(case((ParseTask.status == "pending", 1), else_=0)).label('pending'),
            func.sum(case((ParseTask.status == "processing", 1), else_=0)).label('processing'),
            func.sum(case((ParseTask.status == "completed", 1), else_=0)).label('completed'),
            func.sum(case((ParseTask.status == "failed", 1), else_=0)).label('failed')
        ).first()
        
        stats = {
            "total": stats_query.total or 0,
            "pending": stats_query.pending or 0,
            "processing": stats_query.processing or 0,
            "completed": stats_query.completed or 0,
            "failed": stats_query.failed or 0
        }
        
        return {
            "items": [ParseTaskResponse.model_validate(task) for task in tasks],
            "total": total,
            "page": page,
            "limit": page_size,
            "pages": pages,
            "stats": stats
        }
        
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/my-tasks"})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.get("/list", response_model=PaginatedResponse)
async def get_task_list(
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1, le=100),
    status: Optional[TaskStatus] = None,
    user_id: Optional[int] = None,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取任务列表"""
    try:
        # 构建查询
        query = db.query(ParseTask)
        
        # 普通用户只能看到自己的任务
        if current_user.role != "admin":
            query = query.filter(ParseTask.user_id == current_user.id)
        elif user_id:
            query = query.filter(ParseTask.user_id == user_id)
        
        # 按状态筛选
        if status:
            query = query.filter(ParseTask.status == status)
        
        # 获取总数
        total = query.count()
        
        # 分页查询
        tasks = query.order_by(desc(ParseTask.created_at)).offset((page - 1) * limit).limit(limit).all()
        
        # 计算分页信息
        pages = (total + limit - 1) // limit
        
        return PaginatedResponse(
            items=[ParseTaskResponse.model_validate(task) for task in tasks],
            total=total,
            page=page,
            limit=limit,
            pages=pages
        )
        
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/list"})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.get("/{task_id}", response_model=ParseTaskResponse)
async def get_task_detail(
    task_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取任务详情"""
    try:
        task = db.query(ParseTask).filter(ParseTask.task_id == task_id).first()
        
        if not task:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_404_NOT_FOUND,
                detail="Task not found"
            )
        
        # 检查权限
        if current_user.role != "admin" and task.user_id != current_user.id:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_403_FORBIDDEN,
                detail="Access denied"
            )
        
        return ParseTaskResponse.model_validate(task)
        
    except HTTPException:
        raise
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/detail", "task_id": task_id})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.delete("/{task_id}", response_model=BaseResponse)
async def delete_task(
    task_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """删除任务"""
    try:
        task = db.query(ParseTask).filter(ParseTask.task_id == task_id).first()
        
        if not task:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_404_NOT_FOUND,
                detail="Task not found"
            )
        
        # 检查权限
        if current_user.role != "admin" and task.user_id != current_user.id:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_403_FORBIDDEN,
                detail="Access denied"
            )
        
        # 删除相关文件
        import os
        import shutil
        
        if task.file_path and os.path.exists(task.file_path):
            os.remove(task.file_path)
        
        if task.result_path and os.path.exists(task.result_path):
            if os.path.isdir(task.result_path):
                shutil.rmtree(task.result_path)
            else:
                os.remove(task.result_path)
        
        # 删除解析结果
        db.query(ParseResult).filter(ParseResult.task_id == task.id).delete()
        
        # 删除切片任务
        slice_tasks = db.query(SliceTask).filter(SliceTask.parse_task_id == task.id).all()
        for slice_task in slice_tasks:
            if slice_task.result_path and os.path.exists(slice_task.result_path):
                if os.path.isdir(slice_task.result_path):
                    shutil.rmtree(slice_task.result_path)
                else:
                    os.remove(slice_task.result_path)
        
        db.query(SliceTask).filter(SliceTask.parse_task_id == task.id).delete()
        
        # 删除任务
        db.delete(task)
        db.commit()
        
        api_logger.log_task_event("tasks", "task_deleted", {"task_id": task_id, "user_id": current_user.id})
        
        return BaseResponse(
            success=True,
            message="Task deleted successfully"
        )
        
    except HTTPException:
        raise
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/delete", "task_id": task_id})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.get("/results/{task_id}")
async def get_task_results(
    task_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取任务结果列表"""
    try:
        task = db.query(ParseTask).filter(ParseTask.task_id == task_id).first()
        
        if not task:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_404_NOT_FOUND,
                detail="Task not found"
            )
        
        # 检查权限
        if current_user.role != "admin" and task.user_id != current_user.id:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_403_FORBIDDEN,
                detail="Access denied"
            )
        
        # 获取解析结果
        results = db.query(ParseResult).filter(ParseResult.task_id == task.id).all()
        
        return {
            "task_id": task_id,
            "results": [
                {
                    "id": result.id,
                    "content_type": result.content_type,
                    "file_size": result.file_size,
                    "created_at": result.created_at,
                    "metadata": result.result_metadata
                }
                for result in results
            ]
        }
        
    except HTTPException:
        raise
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/results", "task_id": task_id})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.get("/stats")
async def get_task_stats(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取任务统计信息"""
    try:
        # 构建基础查询
        base_query = db.query(ParseTask)
        if current_user.role != "admin":
            base_query = base_query.filter(ParseTask.user_id == current_user.id)
        
        # 总任务数
        total_tasks = base_query.count()
        
        # 按状态统计
        status_stats = {}
        for status in TaskStatus:
            count = base_query.filter(ParseTask.status == status).count()
            status_stats[status.value] = count
        
        # 今日任务数
        today = datetime.now().date()
        today_tasks = base_query.filter(
            func.date(ParseTask.created_at) == today
        ).count()
        
        # 平均处理时间
        completed_tasks = base_query.filter(
            ParseTask.status == TaskStatus.COMPLETED,
            ParseTask.started_at.isnot(None),
            ParseTask.completed_at.isnot(None)
        ).all()
        
        avg_process_time = 0
        if completed_tasks:
            total_time = sum(
                (task.completed_at - task.started_at).total_seconds()
                for task in completed_tasks
            )
            avg_process_time = total_time / len(completed_tasks)
        
        # 文件类型统计
        file_type_stats = {}
        all_tasks = base_query.all()
        for task in all_tasks:
            ext = task.filename.split('.')[-1].lower() if '.' in task.filename else 'unknown'
            file_type_stats[ext] = file_type_stats.get(ext, 0) + 1
        
        return {
            "total_tasks": total_tasks,
            "today_tasks": today_tasks,
            "status_stats": status_stats,
            "avg_process_time": avg_process_time,
            "file_type_stats": file_type_stats
        }
        
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/stats"})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.post("/{task_id}/cancel", response_model=BaseResponse)
async def cancel_task(
    task_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """取消正在进行的任务"""
    try:
        task = db.query(ParseTask).filter(ParseTask.task_id == task_id).first()
        
        if not task:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_404_NOT_FOUND,
                detail="Task not found"
            )
        
        # 检查权限
        if current_user.role != "admin" and task.user_id != current_user.id:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_403_FORBIDDEN,
                detail="Access denied"
            )
        
        # 只能取消处理中的任务
        if task.status != "processing":
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_400_BAD_REQUEST,
                detail="Only processing tasks can be cancelled"
            )
        
        # 标记任务为取消状态
        task.status = "failed"
        task.error_message = "Task cancelled by user"
        task.completed_at = datetime.now()
        
        db.commit()
        
        api_logger.log_task_event("tasks", "task_cancelled", {"task_id": task_id, "user_id": current_user.id})
        
        return BaseResponse(
            success=True,
            message="Task cancelled successfully"
        )
        
    except HTTPException:
        raise
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/cancel", "task_id": task_id})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


@router.post("/{task_id}/retry", response_model=BaseResponse)
async def retry_task(
    task_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """重试失败的任务"""
    try:
        task = db.query(ParseTask).filter(ParseTask.task_id == task_id).first()
        
        if not task:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_404_NOT_FOUND,
                detail="Task not found"
            )
        
        # 检查权限
        if current_user.role != "admin" and task.user_id != current_user.id:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_403_FORBIDDEN,
                detail="Access denied"
            )
        
        # 只能重试失败的任务
        if task.status != TaskStatus.FAILED:
            raise HTTPException(
                status_code=HTTP_STATUS.HTTP_400_BAD_REQUEST,
                detail="Only failed tasks can be retried"
            )
        
        # 重置任务状态
        task.status = TaskStatus.PENDING
        task.progress = 0
        task.error_message = None
        task.started_at = None
        task.completed_at = None
        
        db.commit()
        
        # 如果是异步任务，添加到后台任务队列
        if task.execution_mode == "async":
            from api.parse import process_parse_task_async
            from fastapi import BackgroundTasks
            
            background_tasks = BackgroundTasks()
            background_tasks.add_task(
                process_parse_task_async,
                task.task_id,
                task.user_id,
                task.file_path,
                task.parse_options
            )
        
        api_logger.log_task_event("tasks", "task_retried", {"task_id": task_id, "user_id": current_user.id})
        
        return BaseResponse(
            success=True,
            message="Task retry initiated successfully"
        )
        
    except HTTPException:
        raise
    except Exception as e:
        api_logger.log_error(e, {"endpoint": "/tasks/retry", "task_id": task_id})
        raise HTTPException(
            status_code=HTTP_STATUS.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Internal server error"
        )


# 导出路由器
tasks_router = router